using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using UnityEngine;

public class LoggerHelper
{
	public static LogLevel CurrentLogLevels;

	private const bool SHOW_STACK = true;

	private static LogWriter m_logWriter;

	public static string DebugFilterStr;

	private static ulong index;

	[CompilerGenerated]
	private static Application.LogCallback _003C_003Ef__mg_0024cache0;

	static LoggerHelper()
	{
		CurrentLogLevels = (LogLevel.DEBUG | LogLevel.INFO | LogLevel.WARNING | LogLevel.ERROR | LogLevel.EXCEPT | LogLevel.CRITICAL);
		DebugFilterStr = string.Empty;
		index = 0uL;
		m_logWriter = new LogWriter();
		Application.RegisterLogCallback(ProcessExceptionReport);
	}

	public static void Release()
	{
		m_logWriter.Release();
	}

	public static void UploadLogFile()
	{
		m_logWriter.UploadTodayLog();
	}

	public static void Debug(object message, bool isShowStack = true, int user = 0)
	{
		if (!(DebugFilterStr != string.Empty) && (CurrentLogLevels & LogLevel.DEBUG) == LogLevel.DEBUG)
		{
			Log(" [DEBUG]: " + ((!isShowStack) ? string.Empty : GetStackInfo()) + message + " Index = " + index++, LogLevel.DEBUG);
		}
	}

	public static void Debug(string filter, object message, bool isShowStack = true)
	{
		if ((!(DebugFilterStr != string.Empty) || !(DebugFilterStr != filter)) && (CurrentLogLevels & LogLevel.DEBUG) == LogLevel.DEBUG)
		{
			Log(" [DEBUG]: " + ((!isShowStack) ? string.Empty : GetStackInfo()) + message, LogLevel.DEBUG);
		}
	}

	public static void Info(object message, bool isShowStack = true)
	{
		if ((CurrentLogLevels & LogLevel.INFO) == LogLevel.INFO)
		{
			Log(" [INFO]: " + ((!isShowStack) ? string.Empty : GetStackInfo()) + message, LogLevel.INFO);
		}
	}

	public static void Warning(object message, bool isShowStack = true)
	{
		if ((CurrentLogLevels & LogLevel.WARNING) == LogLevel.WARNING)
		{
			Log(" [WARNING]: " + ((!isShowStack) ? string.Empty : GetStackInfo()) + message, LogLevel.WARNING);
		}
	}

	public static void Error(object message, bool isShowStack = true)
	{
		if ((CurrentLogLevels & LogLevel.ERROR) == LogLevel.ERROR)
		{
			Log(" [ERROR]: " + message + '\n' + ((!isShowStack) ? string.Empty : GetStacksInfo()), LogLevel.ERROR);
		}
	}

	public static void Critical(object message, bool isShowStack = true)
	{
		if ((CurrentLogLevels & LogLevel.CRITICAL) == LogLevel.CRITICAL)
		{
			Log(" [CRITICAL]: " + message + '\n' + ((!isShowStack) ? string.Empty : GetStacksInfo()), LogLevel.CRITICAL);
		}
	}

	public static void Except(Exception ex, object message = null)
	{
		if ((CurrentLogLevels & LogLevel.EXCEPT) == LogLevel.EXCEPT)
		{
			Exception ex2 = ex;
			while (ex2.InnerException != null)
			{
				ex2 = ex2.InnerException;
			}
			Log(" [EXCEPT]: " + ((message != null) ? (message + "\n") : string.Empty) + ex.Message + ex2.StackTrace, LogLevel.CRITICAL);
		}
	}

	private static string GetStacksInfo()
	{
		StringBuilder stringBuilder = new StringBuilder();
		StackTrace stackTrace = new StackTrace();
		StackFrame[] frames = stackTrace.GetFrames();
		for (int i = 2; i < frames.Length; i++)
		{
			stringBuilder.AppendLine(frames[i].ToString());
		}
		return stringBuilder.ToString();
	}

	private static void Log(string message, LogLevel level, bool writeEditorLog = true)
	{
		string msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff") + message;
		m_logWriter.WriteLog(msg, level, writeEditorLog);
	}

	private static string GetStackInfo()
	{
		StackTrace stackTrace = new StackTrace();
		StackFrame frame = stackTrace.GetFrame(2);
		MethodBase method = frame.GetMethod();
		return $"{method.ReflectedType.Name}.{method.Name}(): ";
	}

	private static void ProcessExceptionReport(string message, string stackTrace, LogType type)
	{
		LogLevel logLevel = LogLevel.DEBUG;
		switch (type)
		{
		case LogType.Assert:
			logLevel = LogLevel.DEBUG;
			break;
		case LogType.Error:
			logLevel = LogLevel.ERROR;
			break;
		case LogType.Exception:
			logLevel = LogLevel.EXCEPT;
			break;
		case LogType.Log:
			logLevel = LogLevel.DEBUG;
			break;
		case LogType.Warning:
			logLevel = LogLevel.WARNING;
			break;
		}
		if (logLevel == (CurrentLogLevels & logLevel))
		{
			Log(" [SYS_" + logLevel + "]: " + message + '\n' + stackTrace, logLevel, writeEditorLog: false);
		}
	}
}
